<?php
/**
 *      [迷你云] (C)2009-2012 南京恒为网络科技.
 *   软件仅供研究与学习使用，如需商用，请访问www.miniyun.cn获得授权
 * 
 */
?>
<?php

class MMoveController
extends MApplicationComponent
implements MIController
{
    private $_userId = null;
    private $_locale = null;
    private $_root   = null;
    
    public function invoke($uri=null)
    {
                                parent::init();
        $params = $_REQUEST;
                if (isset($params) === false) {
            throw new MException(FXP::t('Invalid parameters'));
        }
                        $user               = MUserManager::getInstance()->getCurrentUser();
        $device             = MUserManager::getInstance()->getCurrentDevice();
        $this->_userId      = $user->user_id;
        $user_nick          = $user->user_name;
        $user_device_id   = $device->device_id;

                                $this->_locale = "bytes";
        if (isset($params["locale"])) {
            $this->_locale = $params["locale"];
        }
        if (isset($params["root"]) === false || 
                isset($params["from_path"]) === false || 
                isset($params["to_path"]) === false) {
            throw new MFileopsException(
                                        FXP::t('Bad Request'),
                                        MConst::HTTP_CODE_400);
        }
        $this->_root        = $params["root"];
        $from_path          = $params["from_path"];
        $to_path            = $params["to_path"];

                                $from_path = MUtils::convertStandardPath($from_path);
        $to_path   = MUtils::convertStandardPath($to_path);
        if ($to_path[strlen($to_path)-1] == "/")
        {
                        throw new MFileopsException(
            FXP::t('goal file_name invaild'),
            MConst::HTTP_CODE_403);
        }
        $file_name = MUtils::get_basename($to_path);
        $from_path = "/".$this->_userId.$from_path;
        $to_path   = "/".$this->_userId.$to_path;
                                $is_invalid = MUtils::checkNameInvalid($file_name);
        if ($is_invalid)
        {
            throw new MFileopsException(
            FXP::t('bad request'),
            MConst::HTTP_CODE_400);
        }
                                if (strpos($to_path, $from_path."/") === 0)
        {
            throw new MFileopsException(
            FXP::t('can not move into self child directory'),
            MConst::HTTP_CODE_403);
        }
        if ($to_path == "/{$this->_userId}" || $to_path == "/{$this->_userId}/")
        {
            throw new MFileopsException(
            FXP::t('can not move into null directory'),
            MConst::HTTP_CODE_403);
        }
                                $deleted = null;
        $query_db_goal_file = MFiles::queryAllFilesByPath($to_path);
        if ($query_db_goal_file)
        {
            if ($from_path !== $to_path && 
                $query_db_goal_file[0]["is_deleted"] == false)
            {
                throw new MFileopsException(
                FXP::t('already a folder at the given destination'),
                MConst::HTTP_CODE_403);
            }
                        if ($query_db_goal_file[0]["is_deleted"] == 1) {
                MFiles::deleteById($query_db_goal_file[0]["id"]);
                if ($query_db_goal_file[0]["file_type"] != 0) {                      $deleted = $query_db_goal_file[0]["id"];
                }
                
            }
            
        }
                                $query_db_file = MFiles::queryFilesByPath($from_path);
        if ($query_db_file === false || empty($query_db_file))
        {
            throw new MFileopsException(
            FXP::t('The source file was not found at the specified path'),
            MConst::HTTP_CODE_404);
        }
                                if ($from_path === $to_path)
        {
            $this->buildResult($query_db_file[0]);
            return ;
        }
                                $pathInfo        = MUtils::pathinfo_utf($to_path);
        $parent_path     = $pathInfo["dirname"];
        $create_folder      = new MCreateFolderController();
        $create_folder->_user_device_id   = $user_device_id;
        $create_folder->_user_id          = $this->_userId;
        $parent_file_id     = $create_folder->handlerParentFolder($parent_path);
                                $file_detail = new MFiles();
        $file_detail->file_name         = $file_name;
        $file_detail->file_path         = $to_path;
        $file_detail->file_type         = $query_db_file[0]["file_type"];
        $file_detail->id                = $query_db_file[0]["id"];
        $file_detail->from_path         = $from_path;
        $file_detail->parent_file_id    = $parent_file_id;

        $create_array = array();
                                if ($file_detail->file_type == MConst::OBJECT_TYPE_DIRECTORY)
        {
                                                $ret_value = MFiles::updateMoveChildrenFileDetail($this->_userId, $file_detail);
            if ($ret_value === false)
            {
                throw new MFileopsException(
                FXP::t('No file was not found at the specified path'),
                MConst::HTTP_CODE_404);
            }
                                                $create_array = $this->handleChildrenVersions($create_array,
            $this->_userId,
            $user_nick,
            $from_path,
            $to_path,
            $query_db_file[0]["id"]);
        }
        else
        {
            $file_meta = new MFileMetas();
            $file_meta->version_id = $query_db_file[0]["version_id"];
                                                $file_version = MFileMetas::queryFileMeta($to_path, MConst::VERSION);
            if ($file_version)
            {
                $meta_value = MUtils::getFileVersions($file_meta->version_id,
                MConst::CREATE_FILE,
                $this->_userId,
                $user_nick,
                $file_version[0]["meta_value"]);
                $file_meta->is_add      = false;
            }
            else
            {
                $meta_value = MUtils::getFileVersions($file_meta->version_id,
                MConst::CREATE_FILE,
                $this->_userId,
                $user_nick);
                $file_meta->is_add      = true;
            }
            $file_meta->meta_value = $meta_value;
            $file_meta->file_path  = $to_path;
            $create_array[$to_path] = $file_meta;
        }
                                $ret = MFileMetas::batchCreateFileMetas($create_array, MConst::VERSION);
        if ($ret === false)
        {
            throw new MFileopsException(
            FXP::t('Internal Server Error'),
            MConst::HTTP_CODE_500);
        }
                                foreach ($create_array as $file_meta)
        {
            if ($file_meta->is_add === true)
            {
                                continue;
            }
            MFileMetas::updateFileMeta(
            $file_meta->file_path,
            MConst::VERSION,
            $file_meta->meta_value);
        }

                                $file_detail->event_uuid = MUtils::random_string(MConst::LEN_EVENT_UUID);
        $ret_value = MFiles::updateMoveFileDetail($file_detail);         if ($ret_value === false)
        {
            throw new MFileopsException(
            FXP::t('Internal Server Error'),
            MConst::HTTP_CODE_500);
        }
                                $event_action = MConst::MOVE;
        $ret_value = MEvents::CreateEvents($this->_userId,
                                           $user_device_id, 
                                           $event_action,
                                           $file_detail->from_path,
                                           $file_detail->file_path,
                                           $file_detail->event_uuid
                                           );
        if ($ret_value === false)
        {
            throw new MFileopsException(
            FXP::t('Internal Server Error'),
            MConst::HTTP_CODE_500);
        }
        $query_db_file[0]["file_path"] = $file_detail->file_path;
        if (!empty($deleted)) {
            MFiles::updateParentId($deleted, $file_detail->id);
        }
        $this->buildResult($query_db_file[0], $to_path);
    }

    
    public function buildResult($query_db_file, $to_path=null)
    {
        $is_dir                     = true;
        $size                       = $query_db_file["file_size"];
        $response                   = array();
        
        if ($query_db_file["file_type"] == MConst::OBJECT_TYPE_FILE)
        {
            $mime_type                = "text/plain";
            $is_dir                 = false;
            $response["mime_type"]      = $mime_type;
            $response["thumb_exists"]   = MUtils::isExistThumbnail($mime_type, (int)$query_db_file["file_size"]);
        }
        
        $path                       = $query_db_file["file_path"];
        $index                      = strlen("/{$this->_userId}");
        $path                       = substr($path, $index);
        
        $response["size"]           = MUtils::getSizeByLocale($this->_locale, $size);
        $response["is_deleted"]     = false;
        $response["bytes"]          = intval($size);
        $response["modified"]       = MUtils::formatIntTime($query_db_file["file_update_time"]);
        if ($to_path)
        {
            $path                   = $to_path;
        }
        else 
        {
            $path                   = $query_db_file["file_path"];
        }
        $index                      = strlen("/{$this->_userId}");
        $path                       = substr($path, $index);
        $response["path"]           = $path;
        $response["root"]           = $this->_root;
        $response["is_dir"]         = $is_dir;
        $response["rev"]            = strval($query_db_file["version_id"]);
        $response["revision"]       = intval($query_db_file["version_id"]);

        echo json_encode($response);
    }

    
    public function handleChildrenVersions(
    $create_array,
    $user_id,
    $user_nick,
    $from_path,
    $to_path,
    $parent_file_id)
    {
                $create_array = $this->findAllChildrenFiles(
        $parent_file_id,
        $user_nick,
        $from_path,
        $to_path,
        $create_array);
        if ($create_array === false)         {
            throw new MFileopsException(
            FXP::t('Internal Server Error'),
            MConst::HTTP_CODE_500);
        }
                                $file_versions  = MFileMetas::batchQueryFileMeta(MConst::VERSION, $create_array);
        if ($file_versions === false)         {
            throw new MFileopsException(
            FXP::t('Internal Server Error'),
            MConst::HTTP_CODE_500);
        }
        foreach ($file_versions as $file_version)
        {
                        $file_meta = $create_array[$file_version["file_path"]];
                        $meta_value = MUtils::getFileVersions($file_meta->version_id,
            MConst::CREATE_FILE,
            $user_id,
            $user_nick,
            $file_version["meta_value"]);
            $file_meta->meta_value  = $meta_value;
                        $file_meta->is_add      = false;
        }
        return $create_array;
    }

    
    public function findAllChildrenFiles(
    $parent_file_id,
    $user_nick,
    $from_path,
    $to_path,
    $file_array)
    {
        $query_db_files  = MFiles::queryChildrenFilesByParentFileID($parent_file_id);
        if ($query_db_files === false)
        {
            return false;
        }
        foreach ($query_db_files as $key => $db_file)
        {
            if ($db_file["file_type"] != MConst::OBJECT_TYPE_FILE)
            {
                $file_array = $this->findAllChildrenFiles(
                $db_file["id"],
                $user_nick,
                $from_path,
                $to_path,
                $file_array);
                continue;
            }
                                                $file_path      = $db_file["file_path"];
                                                $file = new MFiles();
            $file->file_path        = $file_path;
            $file->version_id       = $db_file["version_id"];
            $meta_value = MUtils::getFileVersions($file->version_id,
            MConst::CREATE_FILE,
            $db_file["user_id"],
            $user_nick);
            $file->meta_value = $meta_value;
            $file->is_add     = true;             $file_array[$file_path] = $file;
        }
        return $file_array;
    }

}
?>